package com.meta.platform.oplog.aop;

import com.alibaba.fastjson.JSONObject;
import com.meta.framework.common.constant.HttpStatus;
import com.meta.framework.core.CommonRes;
import com.meta.framework.common.utils.spring.SpringUtils;
import com.meta.platform.oplog.entity.OperateLog;
import com.meta.platform.oplog.mapper.OperateLogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Optional;

/**
 * @Description 操作记录，记录的增删改查
 * @Author xieshanwu
 * @Date 2020/2/12 11:09 上午
 */
@Aspect
@Component
public class OperationLogAop {

    private final static Logger LOGGER = LoggerFactory.getLogger("OperateLogAop");
    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(operateAction)")
    public Object doAround(ProceedingJoinPoint joinPoint, OperateAction operateAction) throws Throwable {
        CommonRes result = null;
        try {
            Object[] args = joinPoint.getArgs();
            Object arg = args[0];
            OpRecord opRecord = new OpRecord();
            //根据接口入参获取businessKey和userid
            Method m1 =  arg.getClass().getMethod("getUserId",null);
            Object userId = m1.invoke(arg);
            OperateLog operateLog = new OperateLog();
            operateLog.setIp(operateAction.entityName());
            operateLog.setOperateType(operateAction.operateType().getCode());
            operateLog.setCreateUserId(userId==null ? null : Long.valueOf(Objects.toString(userId)));
            result = (CommonRes)joinPoint.proceed();
            switch (operateAction.operateType()) {
                case UPDATE:
                    // 更新
                    if (!Objects.isNull(result) && isSuccess(result)){
                        Method m =  arg.getClass().getMethod(operateAction.getBusinessKeyMethod(),null);
                        Object businessKey = m.invoke(arg);
                        //根据businessKey获取原值
                        Class service = operateAction.entityServiceClass();
                        Object t = SpringUtils.getBean(service);

                        Method serviceMethod = service.getMethod(operateAction.queryEntityMethod(),String.class);
                        Object entity = serviceMethod.invoke(t,(String)businessKey);
                        operateLog.setBusinessKey(Objects.toString(businessKey));
                        operateLog.setContent("原值："+ JSONObject.toJSONString(entity) +"新值："+ JSONObject.toJSONString(arg));
                        operateLogMapper.insertOperateLog(operateLog);
                    }
                    break;
                case CREATE:
                    if (!Objects.isNull(result) && isSuccess(result)) {
                        //创建接口，需要将新生成businessKey放入data中
                        operateLog.setBusinessKey(Objects.toString(result.get(CommonRes.DATA_TAG)));
                        operateLog.setContent(JSONObject.toJSONString(arg));
                        operateLogMapper.insertOperateLog(operateLog);
                    }
                    break;
                case DELETE:
                    if (!Objects.isNull(result) && isSuccess(result)) {
                        Method m =  arg.getClass().getMethod(operateAction.getBusinessKeyMethod(),null);
                        Object businessKey = m.invoke(arg);
                        operateLog.setBusinessKey(Objects.toString(businessKey));
                        operateLog.setContent(JSONObject.toJSONString(arg));
                        operateLogMapper.insertOperateLog(operateLog);
                    }
                    break;

            }
        } catch (Exception e) {
            LOGGER.error("记录户型操作日志异常",e);
            joinPoint.proceed();
        }
        return result;
    }

    private boolean isSuccess(CommonRes result) {

        result = Optional.ofNullable(result).orElse(new CommonRes());
        return HttpStatus.SUCCESS == (Integer) result.get(CommonRes.CODE_TAG);
    }


}
